/*
尝试three.js，绘制三维板块
*/
<template>
  <div
    id="map"
    class="container"
  />
</template>
<script>
import 'maptalks/dist/maptalks.css'
import * as maptalks from 'maptalks'

import * as THREE from 'three'
import { ThreeLayer } from 'maptalks.three'
import * as cc from '@/utils/cMapConstants'
const geoJson = require('@/static/xiamen.json')
export default {
  name: 'Three1',
  data () {
    return {
      // 地图引擎
      mapEngine: null,
      urlTemplate: 'https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png',
      // urlTemplate: 'https://wprd01.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scl=2&style=8&ltype=11',
      // 子域
      subdomains: ['a', 'b', 'c', 'd'],
      // subdomains: ['a', 'b', 'c'],
      // 署名
      attribution: null,
      // 中心点
      center: [118.13245430046891, 24.495713873147764],
      // 倾斜度
      pitch: 60,
      // toolbar
      // 旋转
      whirl: null,
      // 放大/缩小
      zoom: 12,
      // 轴承
      bearing: 0,
      // 屏幕坐标
      containerPoint: { x: null, y: null },
      // 地图坐标
      coordinatePoint: { x: null, y: null },

      currentArea: {
        name: 'test',
        center: {
          x: 1,
          y: 2
        },
        pointList: []
      }
    }
  },
  mounted () {
    this.initMap()
  },
  methods: {
    /**
             * 初始化地图
             */
    initMap () {
      const _t = this
      // this.$nextTick(() => {
      _t.mapEngine = new maptalks.Map('map', {
        // 默认中心点点位
        center: _t.center,
        // 缩放层级
        zoom: _t.zoom,
        // 倾斜度
        pitch: _t.pitch,
        // 最小缩放层级
        minZoom: 1,
        // 最大缩放层级
        maxZoom: 18,
        baseLayer: new maptalks.TileLayer('base', {
          // 电子地图图层
          urlTemplate: _t.urlTemplate,
          subdomains: _t.subdomains,
          attribution: _t.attribution
        })
      })

      // 创建 区域
      this.drawArea()
      this.drawLine()
    },

    /**
             * 再图层上画面
             */
    drawArea () {
      const _t = this
      const layer = new ThreeLayer('three')
      // 图层三维设置
      layer.setOptions({
        // 地图移动、缩放、旋转时强制渲染
        forceRenderOnMoving: true,
        forceRenderOnZooming: true,
        forceRenderOnRotating: true,
        zIndex: 10
      })

      layer.prepareToDraw = function (gl, scene) {
        _t.create3DPlan2(scene, layer)
      }
      _t.mapEngine.addLayer(layer)
    },
    /**
             * 旧版创建3D
             * @param scene
             * @param layer
             * @returns {ExtrudePolygons}
             */
    create3DPlan (scene, layer) {
      // 创建直线光
      const light = new THREE.DirectionalLight(0xffffff)
      light.position.set(0, -10, 10).normalize()
      scene.add(light)
      // 创建环境光
      scene.add(new THREE.AmbientLight(0xffffff, 0.2))

      // 创建材质
      var material = new THREE.MeshLambertMaterial({ color: cc.defaultPolygonFillColor, opacity: 0.7 })

      const list = []
      const polygons = maptalks.GeoJSON.toGeometry(geoJson)
      polygons.forEach(p => {
        // 该方法是旧版本方法，官方推荐使用toExtrudePolygon
        var mesh = layer.toExtrudeMesh(p, 400, material)

        if (Array.isArray(mesh)) {
          scene.add.apply(scene, mesh)
        } else {
          scene.add(mesh.object3d)
        }
        // infowindow test
        mesh.setInfoWindow({
          content: 'hello world',
          title: 'message',
          animationDuration: 0,
          autoOpenOn: false
        })
        list.push(mesh)
      })
      // 批量添加到图层
      layer.addMesh(list)
    },

    /**
     * 新版创建3D使用方式
     * @param scene
     * @param layer
     */
    create3DPlan2 (scene, layer) {
      // 创建直线光
      const light = new THREE.DirectionalLight(0xffffff)
      light.position.set(0, -10, 10).normalize()
      scene.add(light)
      // 创建环境光
      scene.add(new THREE.AmbientLight(0xffffff, 0.2))

      // 创建材质
      var material = new THREE.MeshLambertMaterial({ color: cc.defaultPolygonFillColor, opacity: 0.7 })

      const options = {
        altitude: 1,
        height: 400,
        bottomHeight: 0,
        topColor: null,
        bottomColor: cc.defaultPolygonFillColor,
        interactive: true
      }

      // 定义高亮材质
      const highlightmaterial = new THREE.MeshBasicMaterial({ color: '#ff87a4', transparent: true, opacity: 0.8 })

      const list = []
      const polygons = maptalks.GeoJSON.toGeometry(geoJson)
      polygons.forEach(p => {
        // 这里源码中，可以找到toExtrudePolygons，但是创建的得到的MultiExtrudePolygons无法正常添加到scence中，所以这里还是用它推荐的方法
        var mesh = layer.toExtrudePolygon(p, options, material)
        if (Array.isArray(mesh)) {
          scene.add.apply(scene, mesh)
        } else {
          scene.add(mesh)
        }

        mesh.setInfoWindow({
          title: p.properties.name,
          content: '<br style="color:#f00">中心点：' + p.properties.center + ' </br>行政区划：' + p.properties.adcode + ' </br>父级行政区划：' + p.properties.parent.adcode + '</div>',
          animationDuration: 0,
          autoOpenOn: false
        })
        mesh.on('mouseover', function (e) {
          e.target.setSymbol(highlightmaterial)
          layer.redraw()
        }).on('mouseout', function (e) {
          e.target.setSymbol(material)
          layer.redraw()
        })
        list.push(mesh)
      })
      // 批量添加到图层
      layer.addMesh(list)
    },
    drawLine () {
      const geometry = maptalks.GeoJSON.toGeometry(geoJson)
      if (geometry) {
        geometry.forEach(g => {
          g.setSymbol({
            // 线色
            lineColor: '#f298bc',
            // 线宽
            lineWidth: 1,
            // 不透明度
            polygonOpacity: 0
          })
          g.setProperties({
            // 高度设置
            altitude: 400
          })
        })
      }
      const options = {
        enableAltitude: true,
        zIndex: 10
      }
      new maptalks.VectorLayer('line', options).addGeometry(geometry).addTo(this.mapEngine)
    }

  }
}
</script>

<style scoped lang="scss">
  html, body {
    margin: 0px;
    height: 1000px;
    width: 100%;
  }

  .container {
    width: 100%;
    height: 100%
  }
</style>
